// 用户请求，登陆、注册、验证码登
import axios from 'axios';
import auth from '@/components/utils/auth';
import { ElMessage } from 'element-plus';
import router from '@/router/router'

// 存储正在请求的接口（用于去重）
const pendingRequests = new Map();

// 生成唯一的请求标识（根据url、方法、参数生成）
const generateKey = (config) => {
    const { url, method, params, data } = config;
    return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&');
};

// 创建 Axios 实例
const service = axios.create({
    baseURL: import.meta.env.VITE_BASE_API, // 基础路径（从环境变量获取）
    // timeout: 6000, // 超时时间（毫秒）
    timeout: 60000, // 超时时间（毫秒）
    withCredentials: true // 允许携带 Cookie（跨域请求时需要）
});

// 请求拦截器：发送请求前处理
service.interceptors.request.use(
    (config) => {

        const requestKey = generateKey(config);

        // 如果请求已存在，取消重复请求
        if (pendingRequests.has(requestKey)) {
            const cancelToken = pendingRequests.get(requestKey);
            cancelToken(); // 取消上一次请求
        }
        // 存储当前请求的取消函数
        const source = axios.CancelToken.source();
        config.cancelToken = source.token;
        pendingRequests.set(requestKey, source.cancel);

        // 1. 设置默认请求头格式
        // 对于大多数接口使用application/json
        if (!config.headers['Content-Type']) {
            config.headers['Content-Type'] = 'application/json;charset=utf-8'
        }
        // 3. 处理token
        // 从Vuex中获取token
        const token = auth.getToken() // 假设在Vuex的getters中定义了getToken方法

        // 判断是否有token，且不是登录/注册接口才添加
        const noTokenUrls = ['/login', '/register'] // 不需要token的接口路径
        const isNoTokenUrl = noTokenUrls.some(url => config.url.includes(url))

        if (token && !isNoTokenUrl) {
            // 添加token到请求头，根据后端要求的格式设置，通常是Bearer token
            config.headers['Authorization'] = `Bearer ${token}`
        }
        return config;
    },
    (error) => {
        // 处理请求错误
        console.error('请求错误：', error);
        return Promise.reject(error);
    }
);
// src/utils/request.js
service.interceptors.response.use(
    (response) => {

        const requestKey = generateKey(response.config);
        pendingRequests.delete(requestKey); // 移除已完成的请求

        // 判断是否为图片请求（可根据 URL 或 responseType 判断）
        const isImageRequest =
            response.config.url.includes('/captcha') ||  // 验证码接口包含 /captcha
            response.config.responseType === 'blob';    // 或显式声明了 blob 类型

        if (isImageRequest) {
            // 图片请求直接返回原始响应数据（二进制流）
            return response.data;
        }

        // 普通 JSON 请求继续验证状态码
        const res = response.data;
        return res;
    },
    (error) => {// 响应错误的处理（状态码 4xx、5xx 等）
        const { response } = error;
        let errorResult = { status: false, message: "未知错误" }; // 默认错误格式
        // 处理 401 未认证错误
        if (response && response.status === 401) {

            if (response.config.url.includes('/login')) {
                errorResult.message = "账号或密码错误"
                return errorResult;
            }

            // 1. 清除本地存储的无效令牌（如 token）
            localStorage.removeItem('park-token');
            localStorage.removeItem('userInfo'); // 可选：清除用户信息

            // 2. 提示用户登录过期或未登录
            ElMessage.error('登录已过期，请重新登录');

            // 3. 跳转到登录页（并记录当前路径，方便登录后返回）
            // 避免重复跳转登录页
            if (router.currentRoute.value.path !== '/login') {
                auth.clearUserInfo()
                router.push({
                    path: '/login',
                    query: { redirect: router.currentRoute.value.fullPath } // 记录当前路径
                });
                window.location.reload();
            }
        }
        // 处理其他错误（如 403 权限不足、500 服务器错误等）
        else if (response) {
            switch (response.status) {
                case 403:
                    errorResult.message = "没有权限访问";
                    break;
                case 404:
                    errorResult.message = "接口不存在";
                    break;
                case 500:
                    errorResult.message = "服务器内部错误";
                    break;
                default:
                    errorResult.message = response.data?.message || "请求失败";
            }
            // 非 401 错误：返回统一格式的错误对象（组件可通过 then 捕获）
            return errorResult;
        }
        // 网络错误（如断网）
        else {
            // 网络错误（无 response）
            errorResult.message = "网络连接失败，请检查网络";
            return errorResult;
        }
    }
);

export default service;